alloc_monitor_pagetable/update_pagetable cleanup.
update_pagetable() is now the only code that (ever) sets
arch.monitor_table. update_pagetable() is also now smart
enough to deal with VMX guests while their paging is still
disabled.
Signed-off-by: michael.fetterman@cl.cam.ac.uk
reset_stack_and_jump(vmx_asm_do_launch);
}
-static void alloc_monitor_pagetable(struct exec_domain *ed)
+unsigned long alloc_monitor_pagetable(struct exec_domain *ed)
{
unsigned long mmfn;
l2_pgentry_t *mpl2e;
mk_l2_pgentry((__pa(d->arch.mm_perdomain_pt) & PAGE_MASK)
| __PAGE_HYPERVISOR);
- ed->arch.monitor_table = mk_pagetable(mmfn << PAGE_SHIFT);
ed->arch.monitor_vtable = mpl2e;
// map the phys_to_machine map into the Read-Only MPT space for this domain
mpl2e[l2_table_offset(RO_MPT_VIRT_START)] =
mk_l2_pgentry(pagetable_val(ed->arch.phys_table) | __PAGE_HYPERVISOR);
+
+ return mmfn;
}
/*
shadow_mode_enable(ed->domain, SHM_enable|SHM_translate|SHM_external);
}
- /* We don't call update_pagetables() as we actively want fields such as
- * the linear_pg_table to be inaccessible so that we bail out early of
- * shadow_fault() in case the vmx guest tries illegal accesses with
- * paging turned off.
- */
- //update_pagetables(ed); /* this assigns shadow_pagetable */
- alloc_monitor_pagetable(ed); /* this assigns monitor_pagetable */
+ update_pagetables(ed);
return 0;
static inline void update_pagetables(struct exec_domain *ed)
{
struct domain *d = ed->domain;
+ int paging_enabled =
+#ifdef CONFIG_VMX
+ !VMX_DOMAIN(ed) ||
+ test_bit(VMX_CPU_STATE_PG_ENABLED, &ed->arch.arch_vmx.cpu_state);
+#else
+ 1;
+#endif
- if ( unlikely(shadow_mode_enabled(d)) )
+ /*
+ * We don't call __update_pagetables() when vmx guest paging is
+ * disabled as we want the linear_pg_table to be inaccessible so that
+ * we bail out early of shadow_fault() if the vmx guest tries illegal
+ * accesses while it thinks paging is turned off.
+ */
+ if ( unlikely(shadow_mode_enabled(d)) && paging_enabled )
{
shadow_lock(d);
__update_pagetables(ed);
shadow_unlock(d);
}
+
if ( !shadow_mode_external(d) )
{
#ifdef __x86_64__
else
ed->arch.monitor_table = ed->arch.guest_table;
}
+ else
+ {
+ // External page tables...
+ // Allocate a monitor page table if we don't already have one.
+ //
+ if ( unlikely(!pagetable_val(ed->arch.monitor_table)) )
+ ed->arch.monitor_table =
+ mk_pagetable(alloc_monitor_pagetable(ed) << PAGE_SHIFT);
+ }
}
#if SHADOW_DEBUG
extern void dump_pageframe_info(struct domain *d);
+extern unsigned long alloc_monitor_pagetable(struct exec_domain *ed);
+
#endif /* __XEN_DOMAIN_H__ */